package servlet;

import com.fasterxml.jackson.databind.ObjectMapper;
import dao.UserDao;
import dao.impl.UserDaoImpl;
import domian.Result;
import domian.ResultStatus;
import domian.User;
import redis.clients.jedis.Jedis;
import service.UserService;
import service.impl.UserServiceImpl;
import utils.Redis;
import utils.ToolSet;
import utils.UploadImageUtils;
import utils.Utils;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

@WebServlet("/loginServlet/*")
@MultipartConfig
public class LoginServlet extends BaseServlet{

    //创建用户数据访问对象
    UserDao ud = new UserDaoImpl();
    /**
     * 用户登录
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    public void login(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {
        //获取请求参数
        String tel = req.getParameter("username");
        String pass = req.getParameter("password");
        //使用md5进行加密,与数据库中的加密后的密码对比
        String password = Utils.md5(pass);

        //调用service
        UserService us = new UserServiceImpl();
        Result result = us.userLogin(tel, password);

        if (result.getCode().equals(503)){
            Jedis jedis = new Jedis();
            //将用户对象转成json字符串
            ObjectMapper om = new ObjectMapper();
            String json = om.writeValueAsString(result.getObj());
            //获取用户客户端标识
            String redisKey = Redis.getRedisKey(req);
            //将json存入redis
            jedis.set(redisKey,json);

            //设置存活时间位一天
            jedis.expire(redisKey,60*60*24);
        }
        //将数据返回前端
        ToolSet.printWriter(resp,result);
    }

    /**
     * 用户注册
     * @param req
     * @param resp
     * @throws IOException
     */
    public void register(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        //获取请求参数
        String tel = req.getParameter("username");
        String pass= req.getParameter("password");
        //密码使用md5进行加密
        String password = Utils.md5(pass);
        String email = req.getParameter("email");

        //调用service
        UserService us = new UserServiceImpl();
        Result result = us.userRegister(tel, password, email);
        //将数据返回前端
        ToolSet.printWriter(resp,result);
    }

    /**
     * 用户注册第二步,可以跳过
     * @param req
     * @param resp
     * @throws IOException
     */
    public void registerTwo(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
        //获取请求参数
//        Part file = req.getPart("file");
//        System.out.println(file);
        Integer uid = Integer.parseInt(req.getParameter("uid"));
        String birth = req.getParameter("birth");
        String nickname = req.getParameter("nickname");
        String realname = req.getParameter("realname");
        String sex = req.getParameter("sex");

        //查找的用户对象
        User userById = ud.findUserById(uid);
        //将需要修改的数据放入对象
        userById.setBirthday(birth);
        userById.setNickname(nickname);
        userById.setRealname(realname);
        userById.setSex(sex);

        //将数据更新至表中
        int i = ud.updateUser(userById);

        //状态信息
        ResultStatus result = null;
        Result re = new Result();
        if (i > 0){
            //基本信息完善成功
            result = ResultStatus.REGISTER_BASICINFO_SUCCESS;
            List<Object> list = new ArrayList<>();
            Collections.addAll(list,uid,nickname);
            re.setObj(list);
        }else {
            //基本信息完善成功
            result = ResultStatus.REGISTER_BASICINFO_ERROR;
        }

        re.setCode(result.getCode());
        re.setMsg(result.getMsg());

        ToolSet.printWriter(resp,re);
    }

    /**
     * 用户登录的第二步，头像上传
     * @param req
     * @param resp
     * @throws IOException
     * @throws ServletException
     */
    public void uploadHead(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
        //接受前端发送过来的请求
        Part filePart = req.getPart("file");

        //返回状态
        ResultStatus res = null;

        if (isPictureFormat(filePart)){ //图片格式正确
            //获取用户id
            Integer uid = Integer.parseInt(req.getParameter("uid"));
            //获取用户信息
            User user = null;
            Jedis jedis = new Jedis();
            //获取用户客户端标识
            String redisKey = Redis.getRedisKey(req);
            String json = jedis.get(redisKey);
            if (json == null || json.isEmpty()){
                user = ud.findUserById(uid);
            }else {
                ObjectMapper om = new ObjectMapper();
                user = om.readValue(json,User.class);
            }

//            System.out.println("用户头像地址：" + filePart);
            // 获取上传的文件名
            String fileName = user.getTel()+"-"+ System.currentTimeMillis() + ".png";
            // 获取本地文件路径
            String headimg = this.getServletContext().getRealPath("headimg");
            File uploadFile = new File(headimg);
            if (!uploadFile.exists()) {
                uploadFile.mkdir();//创建这个目录
            }
            String localFilePath = fileName;
            InputStream is = null;
            FileOutputStream fos = null;
            try {
                is = filePart.getInputStream();
                fos = new FileOutputStream(localFilePath);
                byte[] buff = new byte[1];
                int len;
                while ((len = is.read(buff)) != -1) {
                    fos.write(buff, 0, len);
                }
//                System.out.println("图片的地址：" + localFilePath);
//                System.out.println("文件写入成功！");

            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                assert fos != null;
                fos.close();
                assert is != null;
                is.close();
            }
            //将新的头像名存放在数据库中
            //更新数据库将用户头像字段更新
            user.setHeaderimg(fileName);
            ud.updateUser(user);

            if (json != null && !json.isEmpty()){
                //若用户登录时修改则同步更新redis中的数据
                UserService us = new UserServiceImpl();
                us.userUpdate(user,redisKey);
            }

//            System.out.println("**********************************"+localFilePath);
            //本地文件上转至服务器
            String remoteDirectory = "/www/server/nginx/files/"; // 远程服务器文件夹路径
            String username = "root"; // Linux服务器用户名
            String password = "root"; // Linux服务器密码
            String host = "192.168.17.12"; // Linux服务器IP地址
            UploadImageUtils.uploadImageToServer(localFilePath, host, remoteDirectory, username, password);

            res = ResultStatus.HEAD_PORTRAIT_SUCCESS;
        }else {
            //格式不对上传失败
            res = ResultStatus.HEAD_PORTRAIT_ERROR;
        }

        Result result = new Result();
        result.setCode(res.getCode());
        result.setMsg(res.getMsg());

        //上传状态返回前端
        ToolSet.printWriter(resp,result);


    }

    /**
     * 判断文件格式
     * @param part
     * @return
     */
    protected boolean isPictureFormat(Part part){
        String header = part.getHeader("content-disposition");
//        System.out.println(header);//  form-data; name="file"; filename="tx.png"
        String[] split = header.split(";");
        String filename ="";
        for(String str:split){
            if(str.contains("filename")){
                filename = str.split("\"")[1];
//                System.out.println(filename);//tx.png
            }
        }

        boolean flag = false;//判断文件是否是图片格式
        if (filename.endsWith(".jpg") || filename.endsWith(".png") ||
                filename.endsWith(".jpeg") || filename.endsWith(".webp") ||
                filename.endsWith(".gif") ){
            flag = true;
        }

        return flag;
    }

    /**
     * 判断用户登录状态状态
     * @param req
     * @param resp
     * @throws IOException
     * @throws ServletException
     */
    public void loginStatus(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
        User user = null;
        //获取用户登录信息
        Jedis jedis = new Jedis();
        //获取用户客户端标识
        String redisKey = Redis.getRedisKey(req);
        String json = jedis.get(redisKey);

        if (json != null && !json.isEmpty()){
            ObjectMapper om = new ObjectMapper();
            user = om.readValue(json,User.class);
        }

        //用户对象发送至页面
        ToolSet.printWriter(resp,user);
    }

    /**
     * 退出登录状态
     * @param req
     * @param resp
     * @throws IOException
     * @throws ServletException
     */
    public void logOut(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
        Jedis jedis = new Jedis();
        //获取用户客户端标识
        String redisKey = Redis.getRedisKey(req);
        jedis.del(redisKey);
    }
}
